#include "database.h"
#include <QFileInfo>
#include <QDir>
#include <QSqlQuery>
#include <QSqlRecord>
#include <QSqlError>
#include <QMessageBox>
#include <QApplication>
#include <QStandardPaths>
#include <QDebug>

Database::Database(QObject *parent) : QObject(parent)
{
    db = QSqlDatabase::addDatabase("QSQLITE");
}

Database::~Database()
{
    closeDatabase();
}

bool Database::openDatabase(const QString &dbPath)
{
    QString path = dbPath;
    if (path.isEmpty())
    {
        // 使用应用程序数据目录来存储数据库
        path = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
        QDir dir(path);
        if (!dir.exists())
        {
            dir.mkpath(path);
        }
        path += "/dormitory.db";
    }

    db.setDatabaseName(path);

    if (!db.open())
    {
        qDebug() << "数据库打开失败:" << db.lastError().text();
        return false;
    }

    // 检查表是否存在，不存在则创建
    if (!createTables())
    {
        qDebug() << "创建表失败";
        return false;
    }

    return true;
}

bool Database::closeDatabase()
{
    if (db.isOpen())
    {
        db.close();
    }
    return true;
}

bool Database::exportDatabase(const QString &filePath)
{
    if (!db.isOpen())
    {
        qDebug() << "导出数据库失败: 数据库未打开";
        return false;
    }

    // 确保数据库文件存在
    QString dbFilePath = db.databaseName();
    QFile dbFile(dbFilePath);

    if (!dbFile.exists())
    {
        qDebug() << "导出数据库失败: 数据库文件不存在:" << dbFilePath;
        return false;
    }

    // 执行一个简单查询以确保数据库连接和结构正常
    QSqlQuery testQuery("PRAGMA integrity_check");
    if (!testQuery.exec() || !testQuery.next() || testQuery.value(0).toString() != "ok")
    {
        qDebug() << "导出数据库失败: 数据库完整性检查未通过:" << (testQuery.lastError().text());
        return false;
    }

    // 首先确保目标文件不存在
    QFile targetFile(filePath);
    if (targetFile.exists())
    {
        if (!targetFile.remove())
        {
            qDebug() << "导出数据库失败: 无法删除已存在的目标文件:" << filePath;
            return false;
        }
    }

    // 复制数据库文件到目标位置
    if (!dbFile.copy(filePath))
    {
        qDebug() << "导出数据库失败: 无法复制数据库文件到:" << filePath;
        return false;
    }

    // 将复制后的文件权限设置为可读写
    QFile backupFile(filePath);
    if (!backupFile.setPermissions(QFile::ReadOwner | QFile::WriteOwner |
                                   QFile::ReadUser | QFile::WriteUser |
                                   QFile::ReadGroup | QFile::ReadOther))
    {
        qDebug() << "警告: 无法设置备份文件权限:" << filePath;
    }

    qDebug() << "数据库成功导出到:" << filePath;
    return true;
}

bool Database::importDatabase(const QString &filePath)
{
    // 验证导入文件是否存在
    QFile importFile(filePath);
    if (!importFile.exists())
    {
        qDebug() << "导入数据库失败: 导入文件不存在:" << filePath;
        return false;
    }

    // 验证导入文件是否是有效的SQLite数据库
    if (!validateSqliteFile(filePath))
    {
        qDebug() << "导入数据库失败: 文件不是有效的SQLite数据库:" << filePath;
        return false;
    }

    // 关闭当前数据库连接
    closeDatabase();

    // 获取当前数据库路径
    QString dbFilePath = db.databaseName();
    QFile currentDbFile(dbFilePath);

    // 创建备份，以防导入失败后可以恢复
    QString backupPath = dbFilePath + ".bak";
    QFile backupFile(backupPath);

    // 删除现有的备份文件
    if (backupFile.exists())
    {
        if (!backupFile.remove())
        {
            qDebug() << "导入数据库失败: 无法删除现有备份文件:" << backupPath;
            return false;
        }
    }

    // 如果当前数据库文件存在，创建备份
    bool needRestore = false;
    if (currentDbFile.exists())
    {
        if (!currentDbFile.copy(backupPath))
        {
            qDebug() << "导入数据库失败: 无法创建当前数据库的备份:" << backupPath;
            return false;
        }
        needRestore = true;

        // 删除当前数据库文件
        if (!currentDbFile.remove())
        {
            qDebug() << "导入数据库失败: 无法删除当前数据库文件:" << dbFilePath;
            return false;
        }
    }

    // 复制导入文件到数据库路径
    if (!importFile.copy(dbFilePath))
    {
        qDebug() << "导入数据库失败: 无法复制导入文件到数据库路径:" << dbFilePath;

        // 如果需要，恢复备份
        if (needRestore && backupFile.exists())
        {
            if (currentDbFile.exists())
            {
                currentDbFile.remove();
            }
            backupFile.copy(dbFilePath);
            qDebug() << "已恢复原始数据库备份";
        }

        return false;
    }

    // 设置文件权限
    QFile newDbFile(dbFilePath);
    if (!newDbFile.setPermissions(QFile::ReadOwner | QFile::WriteOwner |
                                  QFile::ReadUser | QFile::WriteUser |
                                  QFile::ReadGroup | QFile::ReadOther))
    {
        qDebug() << "警告: 无法设置导入数据库的权限:" << dbFilePath;
    }

    // 尝试重新打开数据库
    if (!openDatabase(dbFilePath))
    {
        qDebug() << "导入数据库失败: 无法打开导入的数据库:" << dbFilePath;

        // 如果需要，恢复备份
        if (needRestore && backupFile.exists())
        {
            if (currentDbFile.exists())
            {
                currentDbFile.remove();
            }
            backupFile.copy(dbFilePath);
            openDatabase(dbFilePath); // 尝试重新打开原始数据库
            qDebug() << "已恢复原始数据库备份";
        }

        return false;
    }

    // 数据库导入成功，删除备份文件
    if (backupFile.exists())
    {
        backupFile.remove();
    }

    qDebug() << "数据库成功从" << filePath << "导入";
    return true;
}

bool Database::createTables()
{
    QStringList tableQueries;

    // 单元表
    tableQueries << "CREATE TABLE IF NOT EXISTS building_units ("
                    "id INTEGER PRIMARY KEY AUTOINCREMENT,"
                    "name TEXT NOT NULL UNIQUE"
                    ")";

    // 房间表
    tableQueries << "CREATE TABLE IF NOT EXISTS rooms ("
                    "id INTEGER PRIMARY KEY AUTOINCREMENT,"
                    "unit_id INTEGER NOT NULL,"
                    "room_number TEXT NOT NULL,"
                    "FOREIGN KEY (unit_id) REFERENCES building_units(id) ON DELETE CASCADE,"
                    "UNIQUE(unit_id, room_number)"
                    ")";

    // 评分记录表
    tableQueries << "CREATE TABLE IF NOT EXISTS score_records ("
                    "id INTEGER PRIMARY KEY AUTOINCREMENT,"
                    "date TEXT NOT NULL,"
                    "unit_id INTEGER NOT NULL,"
                    "room_id INTEGER NOT NULL,"
                    "score TEXT NOT NULL,"
                    "issues TEXT,"
                    "FOREIGN KEY (unit_id) REFERENCES building_units(id) ON DELETE CASCADE,"
                    "FOREIGN KEY (room_id) REFERENCES rooms(id) ON DELETE CASCADE,"
                    "UNIQUE(date, room_id)"
                    ")";

    QSqlQuery query;
    for (const QString &queryText : tableQueries)
    {
        if (!query.exec(queryText))
        {
            qDebug() << "创建表失败:" << query.lastError().text();
            return false;
        }
    }

    return true;
}

bool Database::initializeDatabase()
{
    return createTables();
}

bool Database::initializeDormitoryData()
{
    if (!db.isOpen())
    {
        return false;
    }

    // 检查是否已经有数据
    QSqlQuery query;
    query.exec("SELECT COUNT(*) FROM building_units");
    if (query.next() && query.value(0).toInt() > 0)
    {
        // 已经有数据，不需要初始化
        return true;
    }

    // 添加单元和房间数据
    db.transaction();

    // 添加单元数据
    QStringList units = {"1单元", "2单元", "3单元"};

    // 房间数据 - 存储格式为 单元名称 -> 房间列表
    QMap<QString, QStringList> rooms;

    // 1单元房间
    QStringList unit1Rooms;
    unit1Rooms << "1-1-201" << "1-1-202" << "1-1-203" << "1-1-204"
               << "1-1-301" << "1-1-302" << "1-1-303" << "1-1-304"
               << "1-1-401" << "1-1-402" << "1-1-403" << "1-1-404"
               << "1-1-501" << "1-1-502" << "1-1-503" << "1-1-504"
               << "1-1-601" << "1-1-602" << "1-1-603" << "1-1-604";
    rooms.insert("1单元", unit1Rooms);

    // 2单元房间
    QStringList unit2Rooms;
    unit2Rooms << "1-2-101" << "1-2-102" << "1-2-103" << "1-2-104"
               << "1-2-201" << "1-2-202" << "1-2-203" << "1-2-204"
               << "1-2-301" << "1-2-302" << "1-2-303" << "1-2-304"
               << "1-2-401" << "1-2-402" << "1-2-403" << "1-2-404"
               << "1-2-501" << "1-2-502" << "1-2-503" << "1-2-504"
               << "1-2-601" << "1-2-602" << "1-2-603" << "1-2-604";
    rooms.insert("2单元", unit2Rooms);

    // 3单元房间
    QStringList unit3Rooms;
    unit3Rooms << "1-3-201" << "1-3-202" << "1-3-203"
               << "1-3-301" << "1-3-302" << "1-3-303"
               << "1-3-401" << "1-3-402" << "1-3-403" << "1-3-404"
               << "1-3-501" << "1-3-502" << "1-3-503" << "1-3-504"
               << "1-3-601" << "1-3-602" << "1-3-603";
    rooms.insert("3单元", unit3Rooms);

    // 插入单元数据
    for (const QString &unit : units)
    {
        if (!addUnit(unit))
        {
            db.rollback();
            return false;
        }

        // 插入该单元的房间
        for (const QString &room : rooms[unit])
        {
            if (!addRoom(unit, room))
            {
                db.rollback();
                return false;
            }
        }
    }

    db.commit();
    return true;
}

QStringList Database::getBuildingUnits()
{
    QStringList units;

    if (!db.isOpen())
    {
        return units;
    }

    QSqlQuery query;
    query.exec("SELECT name FROM building_units ORDER BY name");

    while (query.next())
    {
        units << query.value(0).toString();
    }

    return units;
}

QStringList Database::getRoomsByUnit(const QString &unit)
{
    QStringList rooms;

    if (!db.isOpen())
    {
        return rooms;
    }

    QSqlQuery query;
    query.prepare("SELECT r.room_number FROM rooms r "
                  "JOIN building_units u ON r.unit_id = u.id "
                  "WHERE u.name = ? ORDER BY r.room_number");
    query.addBindValue(unit);

    if (query.exec())
    {
        while (query.next())
        {
            rooms << query.value(0).toString();
        }
    }
    else
    {
        qDebug() << "获取房间列表失败:" << query.lastError().text();
    }

    return rooms;
}

bool Database::addUnit(const QString &unitName)
{
    if (!db.isOpen())
    {
        return false;
    }

    QSqlQuery query;
    query.prepare("INSERT OR IGNORE INTO building_units (name) VALUES (?)");
    query.addBindValue(unitName);

    return query.exec();
}

bool Database::addRoom(const QString &unitName, const QString &roomNumber)
{
    if (!db.isOpen())
    {
        return false;
    }

    // 获取单元ID
    QSqlQuery unitQuery;
    unitQuery.prepare("SELECT id FROM building_units WHERE name = ?");
    unitQuery.addBindValue(unitName);

    if (!unitQuery.exec() || !unitQuery.next())
    {
        return false;
    }

    int unitId = unitQuery.value(0).toInt();

    // 添加房间
    QSqlQuery roomQuery;
    roomQuery.prepare("INSERT OR IGNORE INTO rooms (unit_id, room_number) VALUES (?, ?)");
    roomQuery.addBindValue(unitId);
    roomQuery.addBindValue(roomNumber);

    return roomQuery.exec();
}

bool Database::deleteUnit(const QString &unitName)
{
    if (!db.isOpen())
    {
        return false;
    }

    // 检查单元是否有关联的房间
    QSqlQuery checkRooms;
    checkRooms.prepare("SELECT COUNT(*) FROM rooms r "
                       "JOIN building_units u ON r.unit_id = u.id "
                       "WHERE u.name = ?");
    checkRooms.addBindValue(unitName);

    if (!checkRooms.exec() || !checkRooms.next())
    {
        return false;
    }

    if (checkRooms.value(0).toInt() > 0)
    {
        // 有关联的房间，不能删除
        return false;
    }

    // 删除单元
    QSqlQuery deleteQuery;
    deleteQuery.prepare("DELETE FROM building_units WHERE name = ?");
    deleteQuery.addBindValue(unitName);

    return deleteQuery.exec();
}

bool Database::deleteRoom(const QString &unitName, const QString &roomNumber)
{
    if (!db.isOpen())
    {
        return false;
    }

    QSqlQuery query;
    query.prepare("DELETE FROM rooms WHERE room_number = ? AND unit_id = "
                  "(SELECT id FROM building_units WHERE name = ?)");
    query.addBindValue(roomNumber);
    query.addBindValue(unitName);

    return query.exec();
}

bool Database::updateRoom(const QString &unitName, const QString &oldRoom, const QString &newRoom)
{
    if (!db.isOpen())
    {
        return false;
    }

    QSqlQuery query;
    query.prepare("UPDATE rooms SET room_number = ? WHERE room_number = ? AND unit_id = "
                  "(SELECT id FROM building_units WHERE name = ?)");
    query.addBindValue(newRoom);
    query.addBindValue(oldRoom);
    query.addBindValue(unitName);

    return query.exec();
}

bool Database::hasScoreRecords(const QString &unitName, const QString &roomNumber)
{
    if (!db.isOpen())
    {
        return false;
    }

    QSqlQuery query;
    query.prepare("SELECT COUNT(*) FROM score_records sr "
                  "JOIN rooms r ON sr.room_id = r.id "
                  "JOIN building_units u ON sr.unit_id = u.id "
                  "WHERE u.name = ? AND r.room_number = ?");
    query.addBindValue(unitName);
    query.addBindValue(roomNumber);

    if (!query.exec() || !query.next())
    {
        return false;
    }

    return query.value(0).toInt() > 0;
}

bool Database::deleteRelatedScoreRecords(const QString &unitName, const QString &roomNumber)
{
    if (!db.isOpen())
    {
        return false;
    }

    QSqlQuery query;
    query.prepare("DELETE FROM score_records WHERE unit_id = "
                  "(SELECT id FROM building_units WHERE name = ?) AND room_id = "
                  "(SELECT id FROM rooms WHERE room_number = ? AND unit_id = "
                  "(SELECT id FROM building_units WHERE name = ?))");
    query.addBindValue(unitName);
    query.addBindValue(roomNumber);
    query.addBindValue(unitName);

    return query.exec();
}

QList<Database::ScoreRecord> Database::getScoresByDate(const QString &date)
{
    QList<ScoreRecord> records;

    if (!db.isOpen())
    {
        return records;
    }

    QSqlQuery query;
    query.prepare("SELECT sr.id, sr.date, u.name, r.room_number, sr.score, sr.issues "
                  "FROM score_records sr "
                  "JOIN building_units u ON sr.unit_id = u.id "
                  "JOIN rooms r ON sr.room_id = r.id "
                  "WHERE sr.date = ? "
                  "ORDER BY u.name, r.room_number");
    query.addBindValue(date);

    if (query.exec())
    {
        while (query.next())
        {
            ScoreRecord record;
            record.id = query.value(0).toInt();
            record.date = query.value(1).toString();
            record.unit = query.value(2).toString();
            record.room = query.value(3).toString();
            record.score = query.value(4).toString();
            record.issues = query.value(5).toString();
            records.append(record);
        }
    }
    else
    {
        qDebug() << "获取评分记录失败:" << query.lastError().text();
    }

    return records;
}

QList<Database::ScoreRecord> Database::getScoresByDateAndUnit(const QString &date, const QString &unit)
{
    QList<ScoreRecord> records;

    if (!db.isOpen())
    {
        return records;
    }

    QSqlQuery query;
    query.prepare("SELECT sr.id, sr.date, u.name, r.room_number, sr.score, sr.issues "
                  "FROM score_records sr "
                  "JOIN building_units u ON sr.unit_id = u.id "
                  "JOIN rooms r ON sr.room_id = r.id "
                  "WHERE sr.date = ? AND u.name = ? "
                  "ORDER BY r.room_number");
    query.addBindValue(date);
    query.addBindValue(unit);

    if (query.exec())
    {
        while (query.next())
        {
            ScoreRecord record;
            record.id = query.value(0).toInt();
            record.date = query.value(1).toString();
            record.unit = query.value(2).toString();
            record.room = query.value(3).toString();
            record.score = query.value(4).toString();
            record.issues = query.value(5).toString();
            records.append(record);
        }
    }
    else
    {
        qDebug() << "获取评分记录失败:" << query.lastError().text();
    }

    return records;
}

bool Database::saveScoreRecord(const QString &date, const QString &unit, const QString &room,
                               const QString &score, const QString &issues)
{
    if (!db.isOpen())
    {
        return false;
    }

    // 获取单元ID
    QSqlQuery unitQuery;
    unitQuery.prepare("SELECT id FROM building_units WHERE name = ?");
    unitQuery.addBindValue(unit);

    if (!unitQuery.exec() || !unitQuery.next())
    {
        return false;
    }

    int unitId = unitQuery.value(0).toInt();

    // 获取房间ID
    QSqlQuery roomQuery;
    roomQuery.prepare("SELECT id FROM rooms WHERE room_number = ? AND unit_id = ?");
    roomQuery.addBindValue(room);
    roomQuery.addBindValue(unitId);

    if (!roomQuery.exec() || !roomQuery.next())
    {
        return false;
    }

    int roomId = roomQuery.value(0).toInt();

    // 保存或更新评分记录
    QSqlQuery saveQuery;
    saveQuery.prepare("INSERT OR REPLACE INTO score_records (date, unit_id, room_id, score, issues) "
                      "VALUES (?, ?, ?, ?, ?)");
    saveQuery.addBindValue(date);
    saveQuery.addBindValue(unitId);
    saveQuery.addBindValue(roomId);
    saveQuery.addBindValue(score);
    saveQuery.addBindValue(issues);

    return saveQuery.exec();
}

bool Database::hasScoreRecordForDate(const QString &date, const QString &unit, const QString &room)
{
    if (!db.isOpen())
    {
        return false;
    }

    QSqlQuery query;
    query.prepare("SELECT COUNT(*) FROM score_records sr "
                  "JOIN building_units u ON sr.unit_id = u.id "
                  "JOIN rooms r ON sr.room_id = r.id "
                  "WHERE sr.date = ? AND u.name = ? AND r.room_number = ?");
    query.addBindValue(date);
    query.addBindValue(unit);
    query.addBindValue(room);

    if (!query.exec() || !query.next())
    {
        return false;
    }

    return query.value(0).toInt() > 0;
}

bool Database::deleteScoreRecord(int recordId)
{
    if (!db.isOpen())
    {
        return false;
    }

    QSqlQuery query;
    query.prepare("DELETE FROM score_records WHERE id = ?");
    query.addBindValue(recordId);

    return query.exec();
}

bool Database::deleteScoreRecordsByDate(const QString &date, const QString &unit, const QString &room)
{
    if (!db.isOpen())
    {
        return false;
    }

    QSqlQuery query;
    query.prepare("DELETE FROM score_records WHERE date = ? AND unit_id = "
                  "(SELECT id FROM building_units WHERE name = ?) AND room_id = "
                  "(SELECT id FROM rooms WHERE room_number = ? AND unit_id = "
                  "(SELECT id FROM building_units WHERE name = ?))");
    query.addBindValue(date);
    query.addBindValue(unit);
    query.addBindValue(room);
    query.addBindValue(unit);

    return query.exec();
}

QList<Database::MonthlyStats> Database::getMonthlyStats(const QString &startDate, const QString &endDate)
{
    QList<MonthlyStats> statsList;

    if (!db.isOpen())
    {
        return statsList;
    }

    // 使用MAP来存储房间的统计信息
    QMap<QString, MonthlyStats> statsMap;

    // 获取所有单元和房间
    QSqlQuery roomsQuery;
    roomsQuery.exec("SELECT u.name, r.room_number FROM rooms r "
                    "JOIN building_units u ON r.unit_id = u.id "
                    "ORDER BY u.name, r.room_number");

    while (roomsQuery.next())
    {
        QString unit = roomsQuery.value(0).toString();
        QString room = roomsQuery.value(1).toString();

        MonthlyStats stats;
        stats.unit = unit;
        stats.room = room;
        stats.excellentCount = 0;
        stats.goodCount = 0;
        stats.poorCount = 0;
        stats.fireIssueCount = 0;
        stats.smokingIssueCount = 0;
        stats.sanitaryIssueCount = 0;
        stats.safetyIssueCount = 0;

        statsMap[unit + "|" + room] = stats;
    }

    // 获取选定日期范围内的评分记录
    QSqlQuery scoreQuery;
    scoreQuery.prepare("SELECT u.name, r.room_number, sr.score, sr.issues FROM score_records sr "
                       "JOIN building_units u ON sr.unit_id = u.id "
                       "JOIN rooms r ON sr.room_id = r.id "
                       "WHERE sr.date >= ? AND sr.date <= ?");
    scoreQuery.addBindValue(startDate);
    scoreQuery.addBindValue(endDate);

    if (scoreQuery.exec())
    {
        while (scoreQuery.next())
        {
            QString unit = scoreQuery.value(0).toString();
            QString room = scoreQuery.value(1).toString();
            QString score = scoreQuery.value(2).toString();
            QString issues = scoreQuery.value(3).toString();

            QString key = unit + "|" + room;
            if (statsMap.contains(key))
            {
                MonthlyStats &stats = statsMap[key];

                if (score == "优")
                {
                    stats.excellentCount++;
                }
                else if (score == "良")
                {
                    stats.goodCount++;
                }
                else if (score == "差")
                {
                    stats.poorCount++;

                    // 统计问题类别
                    QStringList issueList = issues.split(",", QString::SkipEmptyParts);
                    for (const QString &issue : issueList)
                    {
                        if (issue == "消防")
                        {
                            stats.fireIssueCount++;
                        }
                        else if (issue == "抽烟")
                        {
                            stats.smokingIssueCount++;
                        }
                        else if (issue == "卫生")
                        {
                            stats.sanitaryIssueCount++;
                        }
                        else if (issue == "安全")
                        {
                            stats.safetyIssueCount++;
                        }
                    }
                }
            }
        }
    }
    else
    {
        qDebug() << "获取评分统计失败:" << scoreQuery.lastError().text();
        return statsList;
    }

    // 将Map转换为List
    for (const MonthlyStats &stats : statsMap.values())
    {
        if (stats.excellentCount > 0 || stats.goodCount > 0 || stats.poorCount > 0)
        {
            statsList.append(stats);
        }
    }

    return statsList;
}

bool Database::validateSqliteFile(const QString &filePath)
{
    // 验证文件是否存在且可读
    QFile file(filePath);
    if (!file.exists() || !file.open(QIODevice::ReadOnly))
    {
        qDebug() << "验证SQLite文件失败: 无法打开文件:" << filePath;
        return false;
    }

    // 检查文件头部是否是SQLite文件标记
    QByteArray header = file.read(16);
    file.close();

    // SQLite文件标记为"SQLite format 3\0"
    if (header.size() < 16 || !header.startsWith("SQLite format 3"))
    {
        qDebug() << "验证SQLite文件失败: 不是有效的SQLite文件格式";
        return false;
    }

    // 尝试临时打开作为SQLite数据库
    {
        QSqlDatabase testDb = QSqlDatabase::addDatabase("QSQLITE", "VALIDATE_CONNECTION");
        testDb.setDatabaseName(filePath);

        if (!testDb.open())
        {
            qDebug() << "验证SQLite文件失败: 无法作为SQLite数据库打开:" << testDb.lastError().text();
            QSqlDatabase::removeDatabase("VALIDATE_CONNECTION");
            return false;
        }

        // 检查数据库是否包含必要的表
        QStringList requiredTables = {"building_units", "rooms", "score_records"};
        QStringList tables = testDb.tables();

        bool hasAllTables = true;
        for (const QString &table : requiredTables)
        {
            if (!tables.contains(table))
            {
                qDebug() << "验证SQLite文件失败: 数据库缺少必要的表:" << table;
                hasAllTables = false;
                break;
            }
        }

        testDb.close();
        QSqlDatabase::removeDatabase("VALIDATE_CONNECTION");

        if (!hasAllTables)
        {
            return false;
        }
    }

    return true;
}